replace atoi, atol, atof (#912)
authortsteven4 <13596209+tsteven4@users.noreply.github.com>
Mon, 15 Aug 2022 13:01:08 +0000 (07:01 -0600)
committerGitHub <noreply@github.com>
Mon, 15 Aug 2022 13:01:08 +0000 (07:01 -0600)
* eliminate usage of atoi

which has possible undefined behavior.

* eliminate a couple more atoi usages.

* eliminate atol usage.

* eliminate use of atof.

32 files changed:
csv_util.cc
defs.h
discard.cc
exif.cc
garmin.cc
garmin_fs.cc
garmin_gpi.cc
garmin_txt.cc
garmin_xt.cc
gdb.cc
gpssim.cc
gpx.cc
gtrnctr.cc
interpolate.cc
jeeps/gpslibusb.cc
jeeps/gpsusbwin.cc
kml.cc
lowranceusr.cc
magproto.cc
mtk_logger.cc
nmea.cc
ozi.cc
radius.cc
random.cc
skytraq.cc
stackfilter.cc
transform.cc
unicsv.cc
util.cc
v900.cc
wbt-200.cc
xcsv.cc

index bff9907a8028c255252deb211d09ddd1341f5232..a656a5e58e30840a6bc45f8e9c0827400e3c25d8 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <cassert>             // for assert
 #include <cmath>               // for fabs
-#include <cstdlib>             // for atof, strtod
+#include <cstdlib>             // for strtod
 #include <cstring>             // for strlen, strchr, strncmp, strcmp, memmove, strcpy, strcspn, strncpy
 
 #include <QByteArray>          // for QByteArray
@@ -322,9 +322,9 @@ ddmmdir_to_degrees(const char* ddmmdir)
   // if not N or E, prepend a '-' to ddmm2degrees input
   // see XT_LAT_NMEA which handles ddmm directly
   if (strchr(ddmmdir, 'W') || strchr(ddmmdir, 'S')) {
-    return ddmm2degrees(- atof(ddmmdir));
+    return ddmm2degrees(- strtod(ddmmdir, nullptr));
   }
-  return ddmm2degrees(atof(ddmmdir));
+  return ddmm2degrees(strtod(ddmmdir, nullptr));
 
 }
 
diff --git a/defs.h b/defs.h
index 5c88eb486756c4baa40eb2053540ec051ccaa00b..d555e73a3da9ac67125a1ce9babea0db40049b18 100644 (file)
--- a/defs.h
+++ b/defs.h
@@ -1173,6 +1173,7 @@ int gb_ptr2int(const void* p);
 void list_codecs();
 void list_timezones();
 QString grapheme_truncate(const QString& input, unsigned int count);
+int xstrtoi(const char* str, char** str_end, int base);
 
 /*
  *  From parse.c
index d0c1e8ca1a38971ed3b348982231f7ea43115fff..7c55a5d9afbb0f311da1a3ed1c3fa289c48679db 100644 (file)
@@ -24,7 +24,7 @@
 #include <QDebug>              // for QDebug
 #include <QRegularExpression>  // for QRegularExpression, QRegularExpression::CaseInsensitiveOption, QRegularExpressionMatch
 
-#include <cstdlib>             // for atoi, atof
+#include <cstdlib>             // for strtod
 
 #include "defs.h"              // for Waypoint, fatal, route_del_wpt, route_disp_all, track_del_wpt, track_disp_all, waypt_del, waypt_disp_all, route_head, rtedata, trkdata, wptdata, fix_none, fix_unknown
 #include "src/core/logging.h"  // for FatalMsg
@@ -149,29 +149,29 @@ QRegularExpression DiscardFilter::generateRegExp(const QString& glob_pattern)
 void DiscardFilter::init()
 {
   if (hdopopt) {
-    hdopf = atof(hdopopt);
+    hdopf = strtod(hdopopt, nullptr);
   } else {
     hdopf = -1.0;
   }
 
   if (vdopopt) {
-    vdopf = atof(vdopopt);
+    vdopf = strtod(vdopopt, nullptr);
   } else {
     vdopf = -1.0;
   }
 
   if (satopt) {
-    satpf = atoi(satopt);
+    satpf = xstrtoi(satopt, nullptr, 10);
   } else {
     satpf = -1;
   }
 
   if (eleminopt) {
-    eleminpf = atoi(eleminopt);
+    eleminpf = xstrtoi(eleminopt, nullptr, 10);
   }
 
   if (elemaxopt) {
-    elemaxpf = atoi(elemaxopt);
+    elemaxpf = xstrtoi(elemaxopt, nullptr, 10);
   }
 
   if (nameopt) {
diff --git a/exif.cc b/exif.cc
index 78c605f0a6d5558d125656d4d33bf682a58a3b74..429e50938b829371b4241ee8fcb1ccad1e0307c6 100644 (file)
--- a/exif.cc
+++ b/exif.cc
@@ -59,7 +59,7 @@
 #include <cmath>                // for fabs, modf, copysign, round, fmax
 #include <cstdint>              // for uint32_t, int32_t, uint16_t, int16_t, uint8_t, INT32_MAX
 #include <cstdio>               // for printf, SEEK_SET, snprintf, SEEK_CUR
-#include <cstdlib>              // for labs, atoi
+#include <cstdlib>              // for labs
 #include <cstring>              // for memcmp, strlen
 #include <type_traits>          // for add_const<>::type
 
@@ -1510,7 +1510,7 @@ ExifFormat::write()
     route_disp_all(nullptr, nullptr, exif_find_wpt_by_time_lambda);
     waypt_disp_all(exif_find_wpt_by_time_lambda);
 
-    qint64 frame = atoi(opt_frame);
+    qint64 frame = xstrtoi(opt_frame, nullptr, 10);
 
     if (exif_wpt_ref == nullptr) {
       warning(MYNAME ": No point with a valid timestamp found.\n");
index 38d54e51aae5938b9076e6ec24c09f3dc6de8089..97b4d3fde55fba6e94b385422c2d9233ff0c75fa 100644 (file)
--- a/garmin.cc
+++ b/garmin.cc
@@ -24,7 +24,7 @@
 #include <cmath>                // for atan2, floor, sqrt
 #include <csetjmp>              // for setjmp
 #include <cstdio>               // for fprintf, fflush, snprintf, sprintf
-#include <cstdlib>              // for atoi, strtol
+#include <cstdlib>              // for strtol
 #include <cstring>              // for memcpy, strlen, strncpy, strchr
 #include <ctime>                // for time_t
 
@@ -302,13 +302,13 @@ rw_init(const QString& fname)
    * If the user provided a short_length, override the calculated value.
    */
   if (snlen) {
-    setshort_length(mkshort_handle, atoi(snlen));
+    setshort_length(mkshort_handle, xstrtoi(snlen, nullptr, 10));
   } else {
     setshort_length(mkshort_handle, receiver_short_length);
   }
 
   if (snwhiteopt) {
-    setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt));
+    setshort_whitespace_ok(mkshort_handle, xstrtoi(snwhiteopt, nullptr, 10));
   }
 
   /*
@@ -1012,7 +1012,7 @@ waypoint_prepare()
       tx_waylist[i]->time_populated = 1;
     }
     if (category) {
-      tx_waylist[i]->category = 1 << (atoi(category) - 1);
+      tx_waylist[i]->category = 1 << (xstrtoi(category, nullptr, 10) - 1);
     }
     if (categorybits) {
       tx_waylist[i]->category = categorybits;
index 3b75854d5fed85efabe106ad0693d6b482cc6fe0..62108942cf83b1b29472ac1bd9a5b5bd92b3926b 100644 (file)
@@ -22,7 +22,7 @@
 
 #include <cassert>                   // for assert
 #include <cstdio>                    // for snprintf, sscanf
-#include <cstdlib>                   // for atof
+#include <cstdlib>                   // for strtod
 #include <cstring>                   // for strncpy
 
 #include <QByteArray>                // for QByteArray
@@ -216,17 +216,17 @@ garmin_fs_xml_convert(const int base_tag, int tag, const QString& qstr, Waypoint
   switch (tag) {
   case 1:
     if (*cdatastr) {
-      WAYPT_SET(waypt, proximity, atof(cdatastr));
+      WAYPT_SET(waypt, proximity, strtod(cdatastr, nullptr));
     }
     break;
   case 2:
     if (*cdatastr) {
-      WAYPT_SET(waypt, temperature, atof(cdatastr));
+      WAYPT_SET(waypt, temperature, strtod(cdatastr, nullptr));
     }
     break;
   case 3:
     if (*cdatastr) {
-      WAYPT_SET(waypt, depth, atof(cdatastr));
+      WAYPT_SET(waypt, depth, strtod(cdatastr, nullptr));
     }
     break;
   case 4:
index 450fcbd6d995c84ab671c4bb690769e238dd9567..aaa1e1fcb1a3e6372a461b6bd7bf7083c7e2e952 100644 (file)
@@ -34,7 +34,6 @@
 #include <cctype>                  // for tolower
 #include <cstdint>                 // for uint32_t, int32_t
 #include <cstdio>                  // for SEEK_CUR, SEEK_SET
-#include <cstdlib>                 // for atoi
 #include <cstring>                 // for strlen, strncmp
 #include <ctime>                   // for time, gmtime, time_t, tm
 #include <memory>                  // for unique_ptr
@@ -1337,7 +1336,7 @@ GarminGPIFormat::wr_deinit()
   gbfclose(fout);
 
   if ((opt_sleep) && !gpsbabel_testmode()) {  /* don't sleep during 'testo' */
-    int sleep = atoi(opt_sleep);
+    int sleep = xstrtoi(opt_sleep, nullptr, 10);
     if (sleep < 1) {
       sleep = 1;
     }
index b12c2a0fd0f4b61f1ed8a1108b11ddece79d3e4b..e0eda354e03fe4a80352909477677002eb91af63 100644 (file)
@@ -28,7 +28,7 @@
 #include <cmath>                   // for fabs, floor
 #include <cstdio>                  // for NULL, snprintf, sscanf
 #include <cstdint>
-#include <cstdlib>                 // for atoi, abs
+#include <cstdlib>                 // for abs
 #include <cstring>                 // for memset, strstr, strcat, strchr, strlen, strcmp, strcpy, strncpy
 #include <ctime>                   // for gmtime, localtime, strftime
 
@@ -751,7 +751,7 @@ garmin_txt_wr_init(const QString& fname)
   gtxt_flags.celsius = (toupper(*get_option_val(opt_temp, "c")) == 'C');
   init_date_and_time_format();
   if (opt_precision) {
-    precision = atoi(opt_precision);
+    precision = xstrtoi(opt_precision, nullptr, 10);
     if (precision < 0) {
       fatal(MYNAME ": Invalid precision (%s)!", opt_precision);
     }
@@ -789,7 +789,7 @@ garmin_txt_wr_init(const QString& fname)
     if (case_ignore_strcmp(opt_utc, "utc") == 0) {
       utc_offs = 0;
     } else {
-      utc_offs = atoi(opt_utc);
+      utc_offs = xstrtoi(opt_utc, nullptr, 10);
     }
     utc_offs *= (60 * 60);
     gtxt_flags.utc = 1;
@@ -1303,7 +1303,7 @@ parse_track_waypoint(const QStringList& lineparts)
       }
       break;
     case 9:
-      WAYPT_SET(wpt, course, atoi(CSTR(str)));
+      WAYPT_SET(wpt, course, xstrtoi(CSTR(str), nullptr, 10));
       break;
     }
   }
index c52a2da2e36010662690fe568cc0553d018e36b3..3a6c4b13af8fc13180241dd8a441e76688fe95fa 100644 (file)
@@ -24,7 +24,6 @@
 */
 
 #include "defs.h"
-#include <cstdlib>
 
 #define MYNAME "Garmin_XT"
 #define GARMIN_XT_ELE 31500/65536
@@ -94,7 +93,7 @@ format_garmin_xt_rd_st_attrs(char* p_trk_name, uint8_t* p_track_color)
 
   // get the option for the processing the track name
   if (opt_trk_header) {
-    method = atoi(opt_trk_header);
+    method = xstrtoi(opt_trk_header, nullptr, 10);
     // if method is out of range set to default
     if ((method < 0) || (method > 1)) {
       method = 0;
@@ -331,7 +330,7 @@ format_garmin_xt_proc_atrk()
 
   // get the option for the processing the track name
   if (opt_trk_header) {
-    method = atoi(opt_trk_header);
+    method = xstrtoi(opt_trk_header, nullptr, 10);
   }
 
   if (! track) {
diff --git a/gdb.cc b/gdb.cc
index db460883945572cba7e29d040f3c2cd76f941d6d..de388f4b5bc69698ea222891e9162c544a884932 100644 (file)
--- a/gdb.cc
+++ b/gdb.cc
@@ -34,7 +34,7 @@
 
 #include <cmath>                   // for fabs
 #include <cstdio>                  // for printf, snprintf, sscanf, SEEK_SET
-#include <cstdlib>                 // for atoi, strtol
+#include <cstdlib>                 // for strtol
 #include <cstring>                 // for memset, strstr, strchr, strcmp, strlen, strncpy
 #include <ctime>                   // for strftime, tm
 #include <iterator>                // for next
@@ -1720,8 +1720,8 @@ GdbFormat::wr_init(const QString& fname)
   fout = gbfopen_le(fname, "wb", MYNAME);
   ftmp = gbfopen_le(nullptr, "wb", MYNAME);
 
-  gdb_category = (gdb_opt_category) ? atoi(gdb_opt_category) : 0;
-  gdb_ver = (gdb_opt_ver && *gdb_opt_ver) ? atoi(gdb_opt_ver) : 0;
+  gdb_category = (gdb_opt_category) ? xstrtoi(gdb_opt_category, nullptr, 10) : 0;
+  gdb_ver = (gdb_opt_ver && *gdb_opt_ver) ? xstrtoi(gdb_opt_ver, nullptr, 10) : 0;
 
   if (gdb_category) {
     if ((gdb_category < 1) || (gdb_category > 16)) {
@@ -1763,7 +1763,7 @@ void
 GdbFormat::write()
 {
   if (gdb_opt_ver) {
-    gdb_ver = atoi(gdb_opt_ver);
+    gdb_ver = xstrtoi(gdb_opt_ver, nullptr, 10);
   }
   write_header();
 
index 138dc139b8fc5a3e263350170b77d6be51f05a88..a599a8ff6cdd4bb0d83b5d04f4060653d2e08572 100644 (file)
--- a/gpssim.cc
+++ b/gpssim.cc
@@ -60,7 +60,7 @@ gpssim_wr_init(const QString& fname)
 {
   fnamestr =  fname;
   trk_count = 0;
-  splitfiles = splitfiles_opt ? atoi(splitfiles_opt) : 0;
+  splitfiles = splitfiles_opt ? xstrtoi(splitfiles_opt, nullptr, 10) : 0;
 
   /* If writing to stdout, never split files */
   if (0 == strcmp("-",splitfiles_opt)) {
@@ -168,7 +168,7 @@ gpssim_write()
       fout = gbfopen(ofname, "wb", MYNAME);
     }
     if (wayptspd && wayptspd[0]) {
-      gpssim_write_spd(atof(wayptspd));
+      gpssim_write_spd(strtod(wayptspd, nullptr));
     }
     waypt_disp_all(gpssim_write_pt);
     if (splitfiles) {
diff --git a/gpx.cc b/gpx.cc
index a54b7359464428f69a3d81172bb13f21321195b1..05e64e66da9a7f50037d3f5f81adff9a8aa6722b 100644 (file)
--- a/gpx.cc
+++ b/gpx.cc
@@ -21,7 +21,7 @@
 
 #include <cmath>                                   // for lround
 #include <cstdio>                                  // for sscanf
-#include <cstdlib>                                 // for atoi, strtod
+#include <cstdlib>                                 // for strtod
 #include <cstring>                                 // for strchr, strncpy
 
 #include <QDate>                                   // for QDate
@@ -98,7 +98,7 @@ GpxFormat::gpx_reset_short_handle()
     setshort_whitespace_ok(mkshort_handle, 0);
   }
 
-  setshort_length(mkshort_handle, atoi(snlen));
+  setshort_length(mkshort_handle, xstrtoi(snlen, nullptr, 10));
 }
 
 void
@@ -1635,7 +1635,7 @@ void
 GpxFormat::write()
 {
 
-  elevation_precision = atoi(opt_elevation_precision);
+  elevation_precision = xstrtoi(opt_elevation_precision, nullptr, 10);
 
   gpx_reset_short_handle();
   auto gpx_waypt_pr_lambda = [this](const Waypoint* waypointp)->void {
index bbc539ff9b419ac0c663117b8c0d95fb81ee0773..e7c404e73ec01e2e6b4b2ba14abe9ab4238aebd5 100644 (file)
@@ -33,7 +33,6 @@
 
 #include <cstdarg>               // for va_end, va_list, va_start
 #include <cstdio>                // for snprintf
-#include <cstdlib>               // for atoi
 #include <iterator>              // for size
 #include <optional>              // for optional
 #include <type_traits>           // for add_const<>::type
@@ -75,7 +74,7 @@ GtrnctrFormat::wr_init(const QString& fname)
       }
     }
   }
-  gtc_course_flag = atoi(opt_course);
+  gtc_course_flag = xstrtoi(opt_course, nullptr, 10);
 }
 
 void
index 90b0ef8018f02d8ccaed36bed86957f452809cd5..f61ff6fab6a12792f4b6d1eeedcc38924df89fd2 100644 (file)
@@ -21,7 +21,7 @@
 
 #include <climits>              // for INT_MAX
 #include <cmath>                // for abs, ceil, isfinite, round
-#include <cstdlib>              // for abs, atoi, strtod
+#include <cstdlib>              // for abs, strtod
 #include <optional>             // for optional
 
 #include <QString>              // for QString
index a0f4c16b9f920b8c4a55877fe6a45731b7407e32..2235271f4ea1e4e4cc4e779be75b0e31d7021883 100644 (file)
@@ -560,7 +560,7 @@ gusb_init(const char* portname, gpsdevh** dh)
     if (0 == strcmp(portname+4, "list")) {
       req_unit_number = -1;
     } else {
-      req_unit_number = atoi(portname + 4);
+      req_unit_number = xstrtoi(portname + 4, nullptr, 10);
     }
   }
   return garmin_usb_scan(lud, req_unit_number);
index 2198a6056c06512e8fec2b7ae20ae9c9a0f7dba1..9da6d227d8bd02490a2d2703d7cebecd2991af84 100644 (file)
@@ -232,7 +232,7 @@ gusb_init(const char* pname, gpsdevh** dh)
     if (0 == strcmp(pname+4, "list")) {
       req_unit_number = -1;
     } else {
-      req_unit_number = atoi(pname+4);
+      req_unit_number = xstrtoi(pname+4, nullptr, 10);
     }
   }
 
diff --git a/kml.cc b/kml.cc
index 9dc7ee3b8ff2d98cf09f23ad9ac3abfaecb69f98..2183e0bae16c01c095a4a8208649d02ddb99e47e 100644 (file)
--- a/kml.cc
+++ b/kml.cc
@@ -23,7 +23,7 @@
 #include <cctype>                       // for tolower, toupper
 #include <cmath>                        // for fabs
 #include <cstdio>                       // for sscanf, printf
-#include <cstdlib>                      // for atoi, atol, atof
+#include <cstdlib>                      // for strtod
 #include <cstring>                      // for strcmp
 #include <optional>                     // for optional
 #include <tuple>                        // for tuple, make_tuple, tie
@@ -69,7 +69,7 @@
 void KmlFormat::kml_init_color_sequencer(unsigned int steps_per_rev)
 {
   if (rotate_colors) {
-    float color_step = atof(opt_rotate_colors);
+    float color_step = strtod(opt_rotate_colors, nullptr);
     if (color_step > 0.0f) {
       // step around circle by given number of degrees for each track(route)
       kml_color_sequencer.step = ((float)kml_color_limit) * 6.0f * color_step / 360.0f;
@@ -393,7 +393,7 @@ void KmlFormat::wr_position_init(const QString& fname)
   posnfilename = fname;
   posnfilenametmp = QStringLiteral("%1-").arg(fname);
   realtime_positioning = 1;
-  max_position_points = atoi(opt_max_position_points);
+  max_position_points = xstrtoi(opt_max_position_points, nullptr, 10);
 }
 
 void KmlFormat::wr_deinit()
@@ -821,7 +821,7 @@ void KmlFormat::kml_output_point(const Waypoint* waypointp, kml_point_type pt_ty
 
   if (export_points) {
     writer->writeStartElement(QStringLiteral("Placemark"));
-    if (atoi(opt_labels)) {
+    if (xstrtoi(opt_labels, nullptr, 10)) {
       writer->writeOptionalTextElement(QStringLiteral("name"), waypointp->shortname);
     }
     writer->writeEmptyElement(QStringLiteral("snippet"));
@@ -1733,8 +1733,8 @@ void KmlFormat::write()
   rotate_colors = (!! opt_rotate_colors);
   trackdata = (!! strcmp("0", opt_trackdata));
   trackdirection = (!! strcmp("0", opt_trackdirection));
-  line_width = atol(opt_line_width);
-  precision = atol(opt_precision);
+  line_width = xstrtoi(opt_line_width, nullptr, 10);
+  precision = xstrtoi(opt_precision, nullptr, 10);
 
   writer->writeStartDocument();
 
index de18681bfce168a9c8f4c3d610a9ea34d01d25be..975eae8c268e673662c575273032fa6bd402bdee 100644 (file)
@@ -89,7 +89,7 @@
 #include <cmath>                  // for M_PI, round, atan, exp, log, tan
 #include <cstdio>                 // for printf, sprintf, SEEK_CUR
 #include <cstdint>                // for int64_t
-#include <cstdlib>                // for atoi, abs
+#include <cstdlib>                // for abs
 #include <cstring>                // for strcmp, strlen
 
 #include <QByteArray>             // for QByteArray
@@ -343,7 +343,7 @@ LowranceusrFormat::wr_init(const QString& fname)
   file_out = gbfopen_le(fname, "wb", MYNAME);
   mkshort_handle = mkshort_new_handle();
   waypt_out_count = 0;
-  writing_version = atoi(opt_wversion);
+  writing_version = xstrtoi(opt_wversion, nullptr, 10);
   if ((writing_version < 2) || (writing_version > 4)) {
     fatal(MYNAME " wversion value %s is not supported !!\n", opt_wversion);
   }
@@ -1891,7 +1891,7 @@ LowranceusrFormat::write()
     gbfputc(0, file_out);
 
     /* device serial number */
-    opt_serialnum_i = atoi(opt_serialnum);
+    opt_serialnum_i = xstrtoi(opt_serialnum, nullptr, 10);
     gbfputint32(opt_serialnum_i, file_out);
 
     /* content description */
index 77380bb017fbbbe2b227af9229a0463c58a0317f..b52becae6914ce15af73f212c2c0752fcafe5e5b 100644 (file)
@@ -24,7 +24,7 @@
 #include <cctype>                  // for isprint, toupper
 #include <cmath>                   // for fabs, lround
 #include <cstdio>                  // for sscanf, size_t
-#include <cstdlib>                 // for atoi, atof, strtoul
+#include <cstdlib>                 // for strtod, strtoul
 #include <cstring>                 // for strchr, strncmp, strlen, memmove, strrchr, memset
 
 #include <QByteArray>              // for QByteArray
@@ -793,7 +793,7 @@ mag_rd_init_common(const QString& portname)
   }
 
   if (bs) {
-    bitrate=atoi(bs);
+    bitrate=xstrtoi(bs, nullptr, 10);
   }
 
   if (!mkshort_handle) {
@@ -850,7 +850,7 @@ mag_wr_init_common(const QString& portname)
 {
   suppress_ack = 0;
   if (bs) {
-    bitrate=atoi(bs);
+    bitrate=xstrtoi(bs, nullptr, 10);
   }
 
   if (waypt_count() > 500) {
@@ -858,7 +858,7 @@ mag_wr_init_common(const QString& portname)
   }
 
   if (cmts) {
-    wptcmtcnt_max = atoi(cmts);
+    wptcmtcnt_max = xstrtoi(cmts, nullptr, 10);
   } else {
     wptcmtcnt_max = MAXCMTCT ;
   }
@@ -983,17 +983,17 @@ mag_trkparse(char* trkmsg)
    * for us.
    */
   parse_istring(trkmsg);
-  double latdeg = atof(ifield[1]);
+  double latdeg = strtod(ifield[1], nullptr);
   char latdir = ifield[2][0];
-  double lngdeg = atof(ifield[3]);
+  double lngdeg = strtod(ifield[3], nullptr);
   char lngdir = ifield[4][0];
-  int alt = atof(ifield[5]);
+  int alt = strtod(ifield[5], nullptr);
   char altunits = ifield[6][0];
   (void)altunits;
   sscanf(ifield[7], "%d.%d", &hms, &fracsecs);
   /* Field 8 is constant */
   /* Field nine is optional track name */
-  int dmy = atoi(ifield[10]);
+  int dmy = xstrtoi(ifield[10], nullptr, 10);
   int sec = hms % 100;
   hms = hms / 100;
   int min = hms % 100;
index 233aa083852307163e5530760e7608ed98acf9f9..7cc640902b23ce381cd040c09f6565b7e6dcfc4c 100644 (file)
@@ -497,7 +497,7 @@ static int mtk_erase()
   // check log status - is logging disabled ?
   do_cmd(CMD_LOG_STATUS, "PMTK182,3,7,", &lstatus, 2);
   if (lstatus) {
-    log_status = atoi(lstatus);
+    log_status = xstrtoi(lstatus, nullptr, 10);
     dbg(3, "LOG Status '%s'\n", lstatus);
     xfree(lstatus);
     lstatus = nullptr;
@@ -565,7 +565,7 @@ static void mtk_read()
   // check log status - is logging disabled ?
   do_cmd(CMD_LOG_STATUS, "PMTK182,3,7,", &fusage, 2);
   if (fusage) {
-    log_enabled = (atoi(fusage) & 2)?1:0;
+    log_enabled = (xstrtoi(fusage, nullptr, 10) & 2)?1:0;
     dbg(3, "LOG Status '%s' -- log %s \n", fusage, log_enabled?"enabled":"disabled");
     xfree(fusage);
     fusage = nullptr;
diff --git a/nmea.cc b/nmea.cc
index 566c5ecfea77269dc440229822201e52ed0306cc..dcdf6c0d62d0f9d181c89fce5e7e766da4263a78 100644 (file)
--- a/nmea.cc
+++ b/nmea.cc
@@ -23,7 +23,7 @@
 #include <cctype>                  // for isprint
 #include <cmath>                   // for fabs
 #include <cstdio>                  // for snprintf, sscanf, fprintf, fputc, stderr
-#include <cstdlib>                 // for atoi, atof, strtod
+#include <cstdlib>                 // for strtod
 #include <cstring>                 // for strncmp, strchr, strlen, strstr, memset, strrchr
 #include <iterator>                // for operator!=, reverse_iterator
 
@@ -294,14 +294,14 @@ NmeaFormat::wr_init(const QString& fname)
   sleepms = -1;
   if (opt_sleep) {
     if (*opt_sleep) {
-      sleepms = 1e3 * atof(opt_sleep);
+      sleepms = 1e3 * strtod(opt_sleep, nullptr);
     } else {
       sleepms = -1;
     }
   }
 
   mkshort_handle = mkshort_new_handle();
-  setshort_length(mkshort_handle, atoi(snlenopt));
+  setshort_length(mkshort_handle, xstrtoi(snlenopt, nullptr, 10));
 
   if (opt_gisteq) {
     opt_gpgga = nullptr;
@@ -1046,7 +1046,7 @@ NmeaFormat::rd_position_init(const QString& fname)
   gbser_flush(gbser_handle);
 
   if (opt_baud) {
-    if (!gbser_set_speed(gbser_handle, atoi(opt_baud))) {
+    if (!gbser_set_speed(gbser_handle, xstrtoi(opt_baud, nullptr, 10))) {
       fatal(MYNAME ": Unable to set baud rate %s\n", opt_baud);
     }
   }
diff --git a/ozi.cc b/ozi.cc
index 615b6a8a937dc10ba9682104c34d4fab96e053f3..a6aed2d883033dcdb9487edf68dcaab4784283d7 100644 (file)
--- a/ozi.cc
+++ b/ozi.cc
@@ -38,7 +38,6 @@
 
 #include <cctype>                 // for tolower
 #include <cmath>                  // for lround
-#include <cstdlib>                // for atoi
 
 #include <QByteArray>             // for QByteArray
 #include <QChar>                  // for operator==, QChar
@@ -466,18 +465,18 @@ wr_init(const QString& fname)
   /* set mkshort options from the command line if applicable */
   if (global_opts.synthesize_shortnames) {
 
-    setshort_length(mkshort_handle, atoi(snlenopt));
+    setshort_length(mkshort_handle, xstrtoi(snlenopt, nullptr, 10));
 
     if (snwhiteopt) {
-      setshort_whitespace_ok(mkshort_handle, atoi(snwhiteopt));
+      setshort_whitespace_ok(mkshort_handle, xstrtoi(snwhiteopt, nullptr, 10));
     }
 
     if (snupperopt) {
-      setshort_mustupper(mkshort_handle, atoi(snupperopt));
+      setshort_mustupper(mkshort_handle, xstrtoi(snupperopt, nullptr, 10));
     }
 
     if (snuniqueopt) {
-      setshort_mustuniq(mkshort_handle, atoi(snuniqueopt));
+      setshort_mustuniq(mkshort_handle, xstrtoi(snuniqueopt, nullptr, 10));
     }
 
     setshort_badchars(mkshort_handle, "\",");
index c085336665a7455a7225b5019f5aa95b485df3f2..a49c5d537b5118f72aa4b47e29417c64ac96d0dd 100644 (file)
--- a/radius.cc
+++ b/radius.cc
@@ -19,7 +19,7 @@
 
  */
 
-#include <cstdlib>          // for atoi, strtod
+#include <cstdlib>          // for strtod
 
 #include <QString>          // for QString
 #include <QtGlobal>         // for qAsConst, QAddConst<>::Type, foreach
@@ -112,7 +112,7 @@ void RadiusFilter::init()
   }
 
   if (maxctarg != nullptr) {
-    maxct = atoi(maxctarg);
+    maxct = xstrtoi(maxctarg, nullptr, 10);
   } else {
     maxct = 0;
   }
index 10c159652192070a32b35fd03d06e73fb496e885..959c1b19bd7875beb0491c717ef79987024ba65c 100644 (file)
--- a/random.cc
+++ b/random.cc
@@ -18,7 +18,6 @@
     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */
 
-#include <cstdlib>              // for atoi
 #include <random>               // for mt19937
 
 #include <QByteArray>           // for QByteArray
@@ -81,7 +80,7 @@ RandomFormat::random_set_generator()
 {
   generator = new std::mt19937;
   if (opt_seed) {
-    generator->seed(atoi(opt_seed));
+    generator->seed(xstrtoi(opt_seed, nullptr, 10));
   } else {
     generator->seed(gpsbabel_time);
   }
@@ -203,7 +202,7 @@ RandomFormat::read()
   Waypoint* prev = nullptr;
   QDateTime time = current_time().toUTC();
 
-  int points = (opt_points) ? atoi(opt_points) : rand_int(128) + 1;
+  int points = (opt_points) ? xstrtoi(opt_points, nullptr, 10) : rand_int(128) + 1;
   if (doing_trks || doing_rtes) {
     head = new route_head;
     if (doing_trks) {
@@ -242,7 +241,7 @@ RandomFormat::rd_position_init(const QString&)
   random_set_generator();
   realtime = new realtime_data;
   if (opt_points) {
-    realtime->points = atoi(opt_points);
+    realtime->points = xstrtoi(opt_points, nullptr, 10);
   }
   realtime->time = current_time().toUTC();
 }
index 6b0e3800b6da6f2971ff37ddf5fe4eafd33a5fd0..dcccda94f9824054c07ba220fb302438c3923ba0 100644 (file)
@@ -34,7 +34,7 @@
 #include <cmath>            // for cos, sin, atan2, pow, sqrt, M_PI
 #include <cstdarg>          // for va_end, va_list, va_start
 #include <cstdio>           // for sscanf, snprintf, vprintf, SEEK_SET
-#include <cstdlib>          // for atoi, free
+#include <cstdlib>          // for free
 #include <cstring>          // for memset
 #include <ctime>            // for time, time_t
 
@@ -520,14 +520,14 @@ SkytraqBase::gpstime_to_timet(int week, int sec) const
    */
   time_t gps_timet = 315964800;     /* Jan 06 1980 0:00 UTC */
 
-  int week_rollover = atoi(opt_gps_week_rollover);
+  int week_rollover = xstrtoi(opt_gps_week_rollover, nullptr, 10);
   if (week_rollover < 0) {
     int current_week = (time(nullptr)-gps_timet)/(7*SECONDS_PER_DAY);
     week_rollover = current_week/1024 - (week > current_week%1024 ? 1 : 0);
   }
   gps_timet += (week+week_rollover*1024)*7*SECONDS_PER_DAY + sec;
 
-  int override = atoi(opt_gps_utc_offset);
+  int override = xstrtoi(opt_gps_utc_offset, nullptr, 10);
   if (override) {
     gps_timet -= override;
     return gps_timet;
@@ -858,7 +858,7 @@ SkytraqBase::skytraq_read_single_sector(unsigned int sector, uint8_t* buf) const
   rd_char(&errors);
   rd_char(&errors);
   rd_char(&errors);
-  skytraq_set_baud(atoi(opt_dlbaud));
+  skytraq_set_baud(xstrtoi(opt_dlbaud, nullptr, 10));
 #endif
 
   cs = skytraq_calc_checksum(buf, i);
@@ -930,9 +930,9 @@ SkytraqBase::skytraq_read_tracks() const
   uint32_t log_wr_ptr;
   uint16_t sectors_free, sectors_total, /*sectors_used_a, sectors_used_b,*/ sectors_used;
   int t, rc, got_sectors, total_sectors_read = 0;
-  int read_at_once = MAX(atoi(opt_read_at_once), 1);
-  int opt_first_sector_val = atoi(opt_first_sector);
-  int opt_last_sector_val = atoi(opt_last_sector);
+  int read_at_once = MAX(xstrtoi(opt_read_at_once, nullptr, 10), 1);
+  int opt_first_sector_val = xstrtoi(opt_first_sector, nullptr, 10);
+  int opt_last_sector_val = xstrtoi(opt_last_sector, nullptr, 10);
   int multi_read_supported = 1;
   gbfile* dumpfile = nullptr;
 
@@ -985,7 +985,7 @@ SkytraqBase::skytraq_read_tracks() const
   db(1, MYNAME ": opt_last_sector_val=%d\n", opt_last_sector_val);
   for (int i = opt_first_sector_val; i < sectors_used; i += got_sectors) {
     for (t = 0, got_sectors = 0; (t < SECTOR_RETRIES) && (got_sectors <= 0); t++) {
-      if (atoi(opt_read_at_once) == 0  ||  multi_read_supported == 0) {
+      if (xstrtoi(opt_read_at_once, nullptr, 10) == 0  ||  multi_read_supported == 0) {
         rc = skytraq_read_single_sector(i, buffer);
         if (rc == res_OK) {
           got_sectors = 1;
@@ -1001,7 +1001,7 @@ SkytraqBase::skytraq_read_tracks() const
         switch (rc) {
         case res_OK:
           got_sectors = read_at_once;
-          read_at_once = MIN(read_at_once*2, atoi(opt_read_at_once));
+          read_at_once = MIN(read_at_once*2, xstrtoi(opt_read_at_once, nullptr, 10));
           break;
 
         case res_NACK:
@@ -1058,7 +1058,7 @@ SkytraqBase::skytraq_probe() const
 {
   int baud_rates[] = { 9600, 230400, 115200, 57600, 4800, 19200, 38400 };
   int baud_rates_count = sizeof(baud_rates)/sizeof(baud_rates[0]);
-  int initbaud = atoi(opt_initbaud);
+  int initbaud = xstrtoi(opt_initbaud, nullptr, 10);
   uint8_t MSG_QUERY_SOFTWARE_VERSION[2] = { 0x02, 0x01 };
   struct {
     uint8_t id;
@@ -1202,7 +1202,7 @@ SkytraqBase::skytraq_read() const
     return;
   }
 
-  int dlbaud = atoi(opt_dlbaud);
+  int dlbaud = xstrtoi(opt_dlbaud, nullptr, 10);
   if (dlbaud != 0  &&  dlbaud != skytraq_baud) {
     skytraq_set_baud(dlbaud);
   }
@@ -1244,8 +1244,8 @@ SkytraqfileFormat::read()
 {
   struct read_state st;
   int got_bytes;
-  int opt_first_sector_val = atoi(opt_first_sector);
-  int opt_last_sector_val = atoi(opt_last_sector);
+  int opt_first_sector_val = xstrtoi(opt_first_sector, nullptr, 10);
+  int opt_last_sector_val = xstrtoi(opt_last_sector, nullptr, 10);
 
   state_init(&st);
   auto* buffer = (uint8_t*) xmalloc(SECTOR_SIZE);
index 5306e88c2df638adff8d5a27096f5d8c5e599eb0..13b4f8f4138f30f13547ac3c907b73cc4607a06e 100644 (file)
@@ -19,8 +19,6 @@
 
  */
 
-#include <cstdlib>  // for atoi
-
 #include "defs.h"
 #include "stackfilter.h"
 
@@ -109,7 +107,7 @@ void StackFilter::init()
   }
 
   if (opt_depth) {
-    swapdepth = atoi(opt_depth);
+    swapdepth = xstrtoi(opt_depth, nullptr, 10);
   }
   if (opt_push) {
     if (opt_pop || opt_append || opt_discard || opt_replace ||
index 32f4aa2a0c67f9205c72829ad60e0cc6a0faa823..e8f3fff35b766dfdb84773b2ac228663232a4a5f 100644 (file)
@@ -21,7 +21,6 @@
  */
 
 #include <cctype>           // for toupper
-#include <cstdlib>          // for atoi
 
 #include <QtGlobal>         // for foreach
 
@@ -140,7 +139,7 @@ void TransformFilter::process()
 
   name_digits = 3;
   if (rpt_name_digits && *rpt_name_digits) {
-    name_digits = atoi(rpt_name_digits);
+    name_digits = xstrtoi(rpt_name_digits, nullptr, 10);
   }
 
   if (opt_waypts != nullptr) {
index b88fc9a03cd54360fe18ca51b4de8f759199520c..5ed30e6c6771bfb45bcf4102a5b9b2d25bb2f39b 100644 (file)
--- a/unicsv.cc
+++ b/unicsv.cc
@@ -22,7 +22,6 @@
 #include <cmath>                   // for fabs, lround
 #include <cstdio>                  // for NULL, sscanf
 #include <cstdint>
-#include <cstdlib>                 // for atoi
 #include <cstring>                 // for memset, strchr, strncpy
 #include <ctime>                   // for gmtime
 
@@ -346,7 +345,7 @@ UnicsvFormat::unicsv_adjust_time(const time_t time, const time_t* date) const
     res += *date;
   }
   if (opt_utc) {
-    res += atoi(opt_utc) * SECONDS_PER_HOUR;
+    res += xstrtoi(opt_utc, nullptr, 10) * SECONDS_PER_HOUR;
   } else {
     struct tm tm = *gmtime(&res);
     res = mklocaltime(&tm);
@@ -1018,7 +1017,7 @@ UnicsvFormat::unicsv_parse_one_line(const QString& ibuf)
     }
 
     if (opt_utc) {
-      wpt->creation_time = wpt->creation_time.addSecs(atoi(opt_utc) * SECONDS_PER_HOUR);
+      wpt->creation_time = wpt->creation_time.addSecs(xstrtoi(opt_utc, nullptr, 10) * SECONDS_PER_HOUR);
     }
   }
 
@@ -1142,8 +1141,8 @@ UnicsvFormat::unicsv_print_data_time(const QDateTime& idt) const
   }
   QDateTime dt = idt;
   if (opt_utc) {
-    //time += atoi(opt_utc) * SECONDS_PER_HOUR;
-    dt = dt.addSecs(atoi(opt_utc) * SECONDS_PER_HOUR);
+    //time += xstrtoi(opt_utc, nullptr, 10) * SECONDS_PER_HOUR;
+    dt = dt.addSecs(xstrtoi(opt_utc, nullptr, 10) * SECONDS_PER_HOUR);
     dt = dt.toUTC();
   }
 
@@ -1535,7 +1534,7 @@ UnicsvFormat::unicsv_waypt_disp_cb(const Waypoint* wpt)
       if (opt_utc) {
         dt = wpt->GetCreationTime().toUTC();
         // We might wrap to a different day by overriding the TZ offset.
-        dt = dt.addSecs(atoi(opt_utc) * SECONDS_PER_HOUR);
+        dt = dt.addSecs(xstrtoi(opt_utc, nullptr, 10) * SECONDS_PER_HOUR);
       } else {
         dt = wpt->GetCreationTime().toLocalTime();
       }
@@ -1550,7 +1549,7 @@ UnicsvFormat::unicsv_waypt_disp_cb(const Waypoint* wpt)
       QTime t;
       if (opt_utc) {
         t = wpt->GetCreationTime().toUTC().time();
-        t = t.addSecs(atoi(opt_utc) * SECONDS_PER_HOUR);
+        t = t.addSecs(xstrtoi(opt_utc, nullptr, 10) * SECONDS_PER_HOUR);
       } else {
         t = wpt->GetCreationTime().toLocalTime().time();
       }
@@ -1743,7 +1742,7 @@ UnicsvFormat::wr_init(const QString& fname)
     unicsv_datum_idx = gt_lookup_datum_index(opt_datum, MYNAME);
   }
 
-  llprec = atoi(opt_prec);
+  llprec = xstrtoi(opt_prec, nullptr, 10);
 }
 
 void
diff --git a/util.cc b/util.cc
index eeccc39fd51de4f0444fc1018ba73314c16f5acb..b1337b327c9bd1f3aec83513a872cc803434f83d 100644 (file)
--- a/util.cc
+++ b/util.cc
@@ -1519,3 +1519,18 @@ QString grapheme_truncate(const QString& input, unsigned int count)
   }
   return output;
 }
+
+int xstrtoi(const char* str, char** str_end, int base)
+{
+  
+  long value = strtol(str, str_end, base);
+  if (value > INT_MAX) {
+    errno = ERANGE;
+    return INT_MAX;
+  }
+  if (value < INT_MIN) {
+    errno = ERANGE;
+    return INT_MIN;
+  }
+  return value;
+}
diff --git a/v900.cc b/v900.cc
index 96cee1b85fe3abffc2d11fdc990022dddbe7c58e..f008cbef5a4984b8b130d878eb7c2ec1d0b0eba1 100644 (file)
--- a/v900.cc
+++ b/v900.cc
@@ -74,7 +74,7 @@ for a little more info, see structures:
 #include "defs.h"
 #include <cassert>
 #include <cstdio>
-#include <cstdlib> // atoi
+#include <cstdlib> // strtod
 
 /* the start of each record (line) is common to both advanced and basic mode.
    it will be parsed by a single common code. hence, it will be easier and clearer
@@ -293,7 +293,7 @@ v900_read()
     /* lat is a string in the form: 31.768380N */
     char c = line.bas.common.latitude_NS;      /* N/S */
     assert(c == 'N' || c == 'S');
-    wpt->latitude = atof(line.bas.common.latitude_num);
+    wpt->latitude = strtod(line.bas.common.latitude_num, nullptr);
     if (c == 'S') {
       wpt->latitude = -wpt->latitude;
     }
@@ -301,31 +301,31 @@ v900_read()
     /* lon is a string in the form: 035.209656E */
     c = line.bas.common.longitude_EW; /* get E/W */
     assert(c == 'E' || c == 'W');
-    line.bas.common.longitude_EW = 0; /* the E will confuse atof(), if not removed */
-    wpt->longitude = atof(line.bas.common.longitude_num);
+    line.bas.common.longitude_EW = 0; /* the E will confuse strtod(), if not removed */
+    wpt->longitude = strtod(line.bas.common.longitude_num, nullptr);
     if (c == 'W') {
       wpt->longitude = -wpt->longitude;
     }
 
-    wpt->altitude = atoi(line.bas.common.height);
+    wpt->altitude = xstrtoi(line.bas.common.height, nullptr, 10);
 
     /* handle date/time fields */
     {
-      int date = atoi(line.bas.common.date);
-      int time = atoi(line.bas.common.time);
+      int date = xstrtoi(line.bas.common.date, nullptr, 10);
+      int time = xstrtoi(line.bas.common.time, nullptr, 10);
       wpt->SetCreationTime(bintime2utc(date, time));
     }
 
-    wpt->speed = KPH_TO_MPS(atoi(line.bas.common.speed));
+    wpt->speed = KPH_TO_MPS(xstrtoi(line.bas.common.speed, nullptr, 10));
     wpt->wpt_flags.speed = 1;
 
-    wpt->course = atoi(line.bas.common.heading);
+    wpt->course = xstrtoi(line.bas.common.heading, nullptr, 10);
     wpt->wpt_flags.course = 1;
 
     if (is_advanced_mode) {
-      wpt->hdop = atof(line.adv.hdop);
-      wpt->vdop = atof(line.adv.vdop);
-      wpt->pdop = atof(line.adv.pdop);
+      wpt->hdop = strtod(line.adv.hdop, nullptr);
+      wpt->vdop = strtod(line.adv.vdop, nullptr);
+      wpt->pdop = strtod(line.adv.pdop, nullptr);
 
       /* handle fix mode (2d, 3d, etc.) */
       if (!strncmp(line.adv.valid,"DGPS", sizeof line.adv.valid)) {
index 15d462b98c464050af5d220a3c7269082ac118a3..bc9164b38cf389235c2b6c32ce54cffe5629c6b7 100644 (file)
@@ -489,13 +489,13 @@ static char* get_param(const char* cmd, char* buf, int len)
 static int get_param_int(const char* cmd)
 {
   char buf[80];
-  return atoi(get_param(cmd, buf, sizeof(buf)));
+  return xstrtoi(get_param(cmd, buf, sizeof(buf)), nullptr, 10);
 }
 
 static double get_param_float(const char* cmd)
 {
   char buf[80];
-  return atof(get_param(cmd, buf, sizeof(buf)));
+  return strtod(get_param(cmd, buf, sizeof(buf)), nullptr);
 }
 
 /* Decompose binary date into discreet fields */
diff --git a/xcsv.cc b/xcsv.cc
index 0c9d3e19e8fc4ff12350de1232edb629dd6d6e82..44e9cfe7846c5bd96fc53fdfb535ba533d0ea0e2 100644 (file)
--- a/xcsv.cc
+++ b/xcsv.cc
@@ -27,7 +27,7 @@
 #include <cctype>                     // for isdigit, tolower
 #include <cmath>                      // for fabs, pow
 #include <cstdio>                     // for snprintf, sscanf
-#include <cstdlib>                    // for atof, atoi, strtod
+#include <cstdlib>                    // for strtod
 #include <cstring>                    // for strlen, strncmp, strcmp, memset
 #include <ctime>                      // for gmtime, localtime, time_t, mktime, strftime
 #include <optional>                   // for optional
@@ -443,7 +443,7 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
   /* LATITUDE CONVERSIONS**************************************************/
   case XcsvStyle::XT_LAT_DECIMAL:
     /* latitude as a pure decimal value */
-    wpt->latitude = atof(s);
+    wpt->latitude = strtod(s, nullptr);
     break;
   case XcsvStyle::XT_LAT_DECIMALDIR:
   case XcsvStyle::XT_LAT_DIRDECIMAL:
@@ -452,7 +452,7 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
     break;
   case XcsvStyle::XT_LAT_INT32DEG:
     /* latitude as a 32 bit integer offset */
-    wpt->latitude = intdeg_to_dec((int) atof(s));
+    wpt->latitude = intdeg_to_dec((int) strtod(s, nullptr));
     break;
   case XcsvStyle::XT_LAT_HUMAN_READABLE:
     human_to_dec(value, &wpt->latitude, &wpt->longitude, 1);
@@ -461,13 +461,13 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
     wpt->latitude = ddmmdir_to_degrees(s);
     break;
   case XcsvStyle::XT_LAT_NMEA:
-    wpt->latitude = ddmm2degrees(atof(s));
+    wpt->latitude = ddmm2degrees(strtod(s, nullptr));
     break;
   // XT_LAT_10E is handled outside the switch.
   /* LONGITUDE CONVERSIONS ***********************************************/
   case XcsvStyle::XT_LON_DECIMAL:
     /* longitude as a pure decimal value */
-    wpt->longitude = atof(s);
+    wpt->longitude = strtod(s, nullptr);
     break;
   case XcsvStyle::XT_LON_DECIMALDIR:
   case XcsvStyle::XT_LON_DIRDECIMAL:
@@ -476,7 +476,7 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
     break;
   case XcsvStyle::XT_LON_INT32DEG:
     /* longitude as a 32 bit integer offset  */
-    wpt->longitude = intdeg_to_dec((int) atof(s));
+    wpt->longitude = intdeg_to_dec((int) strtod(s, nullptr));
     break;
   case XcsvStyle::XT_LON_HUMAN_READABLE:
     human_to_dec(value, &wpt->latitude, &wpt->longitude, 2);
@@ -485,7 +485,7 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
     wpt->longitude = ddmmdir_to_degrees(s);
     break;
   case XcsvStyle::XT_LON_NMEA:
-    wpt->longitude = ddmm2degrees(atof(s));
+    wpt->longitude = ddmm2degrees(strtod(s, nullptr));
     break;
   // case XcsvStyle::XT_LON_10E is handled outside the switch.
   /* LAT AND LON CONVERSIONS ********************************************/
@@ -519,20 +519,20 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
                       &wpt->latitude, &wpt->longitude, MYNAME);
     break;
   case XcsvStyle::XT_UTM_ZONE:
-    parse_data->utm_zone = atoi(s);
+    parse_data->utm_zone = xstrtoi(s, nullptr, 10);
     break;
   case XcsvStyle::XT_UTM_ZONEC:
     parse_data->utm_zonec = s[0];
     break;
   case XcsvStyle::XT_UTM_ZONEF:
-    parse_data->utm_zone = atoi(s);
+    parse_data->utm_zone = xstrtoi(s, nullptr, 10);
     parse_data->utm_zonec = s[strlen(s) - 1];
     break;
   case XcsvStyle::XT_UTM_EASTING:
-    parse_data->utm_easting = atof(s);
+    parse_data->utm_easting = strtod(s, nullptr);
     break;
   case XcsvStyle::XT_UTM_NORTHING:
-    parse_data->utm_northing = atof(s);
+    parse_data->utm_northing = strtod(s, nullptr);
     break;
   case XcsvStyle::XT_UTM: {
     char* ss;
@@ -578,25 +578,25 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
 
   /* PATH CONVERSIONS ************************************************/
   case XcsvStyle::XT_PATH_SPEED:
-    WAYPT_SET(wpt, speed, atof(s));
+    WAYPT_SET(wpt, speed, strtod(s, nullptr));
     break;
   case XcsvStyle::XT_PATH_SPEED_KPH:
-    WAYPT_SET(wpt, speed, KPH_TO_MPS(atof(s)));
+    WAYPT_SET(wpt, speed, KPH_TO_MPS(strtod(s, nullptr)));
     break;
   case XcsvStyle::XT_PATH_SPEED_MPH:
-    WAYPT_SET(wpt, speed, MPH_TO_MPS(atof(s)));
+    WAYPT_SET(wpt, speed, MPH_TO_MPS(strtod(s, nullptr)));
     break;
   case XcsvStyle::XT_PATH_SPEED_KNOTS:
-    WAYPT_SET(wpt, speed, KNOTS_TO_MPS(atof(s)));
+    WAYPT_SET(wpt, speed, KNOTS_TO_MPS(strtod(s, nullptr)));
     break;
   case XcsvStyle::XT_PATH_COURSE:
-    WAYPT_SET(wpt, course, atof(s));
+    WAYPT_SET(wpt, course, strtod(s, nullptr));
     break;
 
   /* TIME CONVERSIONS ***************************************************/
   case XcsvStyle::XT_EXCEL_TIME:
     /* Time as Excel Time  */
-    wpt->SetCreationTime(excel_to_timet(atof(s)));
+    wpt->SetCreationTime(excel_to_timet(strtod(s, nullptr)));
     break;
   case XcsvStyle::XT_TIMET_TIME: {
     /* Time as time_t */
@@ -655,11 +655,11 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
   /* GEOCACHING STUFF ***************************************************/
   case XcsvStyle::XT_GEOCACHE_DIFF:
     /* Geocache Difficulty as an int */
-    wpt->AllocGCData()->diff = atof(s) * 10;
+    wpt->AllocGCData()->diff = strtod(s, nullptr) * 10;
     break;
   case XcsvStyle::XT_GEOCACHE_TERR:
     /* Geocache Terrain as an int */
-    wpt->AllocGCData()->terr = atof(s) * 10;
+    wpt->AllocGCData()->terr = strtod(s, nullptr) * 10;
     break;
   case XcsvStyle::XT_GEOCACHE_TYPE:
     /* Geocache Type */
@@ -697,19 +697,19 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
 
   /* GPS STUFF *******************************************************/
   case XcsvStyle::XT_GPS_HDOP:
-    wpt->hdop = atof(s);
+    wpt->hdop = strtod(s, nullptr);
     break;
   case XcsvStyle::XT_GPS_VDOP:
-    wpt->vdop = atof(s);
+    wpt->vdop = strtod(s, nullptr);
     break;
   case XcsvStyle::XT_GPS_PDOP:
-    wpt->pdop = atof(s);
+    wpt->pdop = strtod(s, nullptr);
     break;
   case XcsvStyle::XT_GPS_SAT:
-    wpt->sat = atoi(s);
+    wpt->sat = xstrtoi(s, nullptr, 10);
     break;
   case XcsvStyle::XT_GPS_FIX:
-    wpt->fix = (fix_type)(atoi(s)-(fix_type)1);
+    wpt->fix = (fix_type)(xstrtoi(s, nullptr, 10)-(fix_type)1);
     if (wpt->fix < fix_2d) {
       if (!case_ignore_strcmp(value, "none")) {
         wpt->fix = fix_none;
@@ -727,7 +727,7 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
     parse_data->rte_name = csv_stringtrim(value, enclosure, 0);
     break;
   case XcsvStyle::XT_TRACK_NEW:
-    parse_data->new_track = atoi(s);
+    parse_data->new_track = xstrtoi(s, nullptr, 10);
     break;
   case XcsvStyle::XT_TRACK_NAME:
     parse_data->trk_name = csv_stringtrim(value, enclosure, 0);
@@ -735,31 +735,31 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
 
   /* OTHER STUFF ***************************************************/
   case XcsvStyle::XT_PATH_DISTANCE_METERS:
-    wpt->odometer_distance = atof(s);
+    wpt->odometer_distance = strtod(s, nullptr);
     break;
   case XcsvStyle::XT_PATH_DISTANCE_KM:
-    wpt->odometer_distance = atof(s) * 1000.0;
+    wpt->odometer_distance = strtod(s, nullptr) * 1000.0;
     break;
   case XcsvStyle::XT_PATH_DISTANCE_MILES:
-    wpt->odometer_distance = MILES_TO_METERS(atof(s));
+    wpt->odometer_distance = MILES_TO_METERS(strtod(s, nullptr));
     break;
   case XcsvStyle::XT_PATH_DISTANCE_NAUTICAL_MILES:
-    wpt->odometer_distance = NMILES_TO_METERS(atof(s));
+    wpt->odometer_distance = NMILES_TO_METERS(strtod(s, nullptr));
     break;
   case XcsvStyle::XT_HEART_RATE:
-    wpt->heartrate = atoi(s);
+    wpt->heartrate = xstrtoi(s, nullptr, 10);
     break;
   case XcsvStyle::XT_CADENCE:
-    wpt->cadence = atoi(s);
+    wpt->cadence = xstrtoi(s, nullptr, 10);
     break;
   case XcsvStyle::XT_POWER:
-    wpt->power = atof(s);
+    wpt->power = strtod(s, nullptr);
     break;
   case XcsvStyle::XT_TEMPERATURE:
-    wpt->temperature = atof(s);
+    wpt->temperature = strtod(s, nullptr);
     break;
   case XcsvStyle::XT_TEMPERATURE_F:
-    wpt->temperature = (FAHRENHEIT_TO_CELSIUS(atof(s)));
+    wpt->temperature = (FAHRENHEIT_TO_CELSIUS(strtod(s, nullptr)));
     break;
   /* GMSD ****************************************************************/
   case XcsvStyle::XT_COUNTRY: {
@@ -804,9 +804,9 @@ XcsvFormat::xcsv_parse_val(const QString& value, Waypoint* wpt, const XcsvStyle:
   break;
   case XcsvStyle::XT_unused:
     if (strncmp(fmp.key.constData(), "LON_10E", 7) == 0) {
-      wpt->longitude = atof(s) / pow(10.0, atof(fmp.key.constData()+7));
+      wpt->longitude = strtod(s, nullptr) / pow(10.0, strtod(fmp.key.constData()+7, nullptr));
     } else if (strncmp(fmp.key.constData(), "LAT_10E", 7) == 0) {
-      wpt->latitude = atof(s) / pow(10.0, atof(fmp.key.constData()+7));
+      wpt->latitude = strtod(s, nullptr) / pow(10.0, strtod(fmp.key.constData()+7, nullptr));
     } else {
       warning(MYNAME ": Unknown style directive: %s\n", fmp.key.constData());
     }
@@ -1053,7 +1053,7 @@ XcsvFormat::xcsv_waypt_pr(const Waypoint* wpt)
       buff = QString::asprintf(fmp.printfc.constData(), "");
       break;
     case XcsvStyle::XT_INDEX:
-      buff = QString::asprintf(fmp.printfc.constData(), waypt_out_count + atoi(fmp.val.constData()));
+      buff = QString::asprintf(fmp.printfc.constData(), waypt_out_count + xstrtoi(fmp.val.constData(), nullptr, 10));
       break;
     case XcsvStyle::XT_CONSTANT: {
       auto cp = XcsvStyle::xcsv_get_char_from_constant_table(fmp.val.constData());
@@ -1536,9 +1536,9 @@ XcsvFormat::xcsv_waypt_pr(const Waypoint* wpt)
       break;
     case XcsvStyle::XT_unused:
       if (strncmp(fmp.key.constData(), "LON_10E", 7) == 0) {
-        buff = QString::asprintf(fmp.printfc.constData(), lon * pow(10.0, atof(fmp.key.constData()+7)));
+        buff = QString::asprintf(fmp.printfc.constData(), lon * pow(10.0, strtod(fmp.key.constData()+7, nullptr)));
       } else if (strncmp(fmp.key.constData(), "LAT_10E", 7) == 0) {
-        buff = QString::asprintf(fmp.printfc.constData(), lat * pow(10.0, atof(fmp.key.constData()+7)));
+        buff = QString::asprintf(fmp.printfc.constData(), lat * pow(10.0, strtod(fmp.key.constData()+7, nullptr)));
       }
       break;
     default:
@@ -1913,19 +1913,19 @@ XcsvFormat::wr_init(const QString& fname)
   if (global_opts.synthesize_shortnames) {
 
     if (snlenopt) {
-      setshort_length(xcsv_file->mkshort_handle, atoi(snlenopt));
+      setshort_length(xcsv_file->mkshort_handle, xstrtoi(snlenopt, nullptr, 10));
     }
 
     if (snwhiteopt) {
-      setshort_whitespace_ok(xcsv_file->mkshort_handle, atoi(snwhiteopt));
+      setshort_whitespace_ok(xcsv_file->mkshort_handle, xstrtoi(snwhiteopt, nullptr, 10));
     }
 
     if (snupperopt) {
-      setshort_mustupper(xcsv_file->mkshort_handle, atoi(snupperopt));
+      setshort_mustupper(xcsv_file->mkshort_handle, xstrtoi(snupperopt, nullptr, 10));
     }
 
     if (snuniqueopt) {
-      setshort_mustuniq(xcsv_file->mkshort_handle, atoi(snuniqueopt));
+      setshort_mustuniq(xcsv_file->mkshort_handle, xstrtoi(snuniqueopt, nullptr, 10));
     }
 
     setshort_badchars(xcsv_file->mkshort_handle, CSTR(xcsv_style->badchars));